package tetris;

/**
 * Created by IntelliJ IDEA.
 * User: raycom
 * Date: 26.09.10
 * Time: 13:16
 */
public class CharBoard implements Board<String> {

    private static final char EMPTY_CELL_CHAR = '*';
    private final static int MAX_ROWS = 40, MAX_COLUMNS = 20;

    private char[][] charBoardArray;
    private int rows, columns;
    private Block fallingBlock;
    private int dropColumn;
    private int fallingBlockRow;

    private boolean gameOver = false;

    public CharBoard(int rows, int columns) throws IncorrectBoardParameters {

        if (rows > MAX_ROWS)
            throw new IncorrectBoardParameters("row size out of range");
        if (columns > MAX_COLUMNS)
            throw new IncorrectBoardParameters("columns size out of range");
        this.rows = rows;
        this.columns = columns;
        dropColumn = (columns / 2);
        if (columns % 2 == 0) {
            dropColumn--;
        }
        fallingBlockRow = 0;

        charBoardArray = new char[rows][columns];
        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < columns; i++) {
                charBoardArray[j][i] = '*';

            }
        }

    }

    public String render() {
        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < columns; i++) {
                sb.append(charBoardArray[j][i]);
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    public Boolean isFallingBlock() {
        return (fallingBlock != null);
    }

    public void drop(Block block) throws DuplicatedFallingBlockException {
        if (isFallingBlock()) {
            throw new DuplicatedFallingBlockException();
        }
        fallingBlock = block;
        charBoardArray[0][dropColumn] = block.toChar();
        fallingBlockRow = 0;
        if (canMove()) {
            gameOver = true;
            fallingBlock = null;
        } else {
            gameOver = false;
        }

    }

    public void tick() {
        if (isGameOver()) {
            throw new IllegalStateException("Game is stopped!!!");
        }

        int newRow = fallingBlockRow + 1;
        if (fallingBlock == null) {
            drop(new CharBlock(CharBlock.FILLED_CELL_CHAR));
        } else {
            charBoardArray[newRow][dropColumn] = fallingBlock.toChar();
            charBoardArray[fallingBlockRow][dropColumn] = EMPTY_CELL_CHAR;
            fallingBlockRow++;

            if (canMove()) {
                fallingBlock = null;
                fallingBlockRow = 0;
            }
        }
    }

    private boolean canMove() {
        int newRow = fallingBlockRow + 1;
        return (newRow >= rows || charBoardArray[newRow][dropColumn] != EMPTY_CELL_CHAR);
    }

    public Boolean isGameOver() {
        return gameOver;
    }
}
